package top.rzhsky.controller;

import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.scene.control.*;
import javafx.scene.input.*;
import javafx.scene.layout.HBox;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
import javafx.util.Callback;
import top.rzhsky.bean.Message;
import top.rzhsky.bean.MessageRecord;
import top.rzhsky.bean.Type;
import top.rzhsky.bean.User;
import top.rzhsky.util.AlertUtil;
import top.rzhsky.util.IOUtil;
import top.rzhsky.util.MyCallBack;

import java.io.*;
import java.util.*;
import java.util.logging.Logger;

public class ImController {
    @FXML
    private Label nickName;
    @FXML
    private Label account;
    @FXML
    private Label birth;
    @FXML
    private Label sex;
    @FXML
    private ListView userList;
    @FXML
    private ListView messageList;
    @FXML
    private TextArea messageBox;
    @FXML
    private Label count;

    private User fromUser;
    private User toUser;

    private Type type;

    private Message message;

    public void setFromUser(User fromUser) {
        this.fromUser = fromUser;
    }

    public void setToUser(User toUser) {
        this.toUser = toUser;
    }

    public void setNickName(String nickNameContext) {
        this.nickName.setText(nickNameContext);
    }

    public void setAccount(String accountContext) {
        this.account.setText(accountContext);
    }

    public void setBirth(String birthContext) {
        this.birth.setText(birthContext);
    }

    public void setSex(String sexContext) {
        this.sex.setText(sexContext);
    }

    public void setType(Type type) {
        this.type = type;
    }

    public void setMessage(Message message) {
        this.message = message;
    }

    private Logger logger = Logger.getLogger("ImController");

    public void setUserList(Message msg) {
        logger.info("setUserList() method Enter");
        Platform.runLater(() -> {
            count.setText("当前在线人数：" + msg.getUserList().size());

            ArrayList<User> list = new ArrayList<>(msg.getHasRegister());
            ObservableList<User> users = FXCollections.observableList(list);
            this.userList.setItems(users);
            this.userList.setCellFactory(new Callback<ListView<User>, ListCell<User>>() {
                @Override
                public ListCell<User> call(ListView param) {
                    return new ListCell<User>() {
                        @Override
                        protected void updateItem(User user, boolean empty) {
                            super.updateItem(user, empty);
                            setGraphic(null);
                            setText(null);
                            if (user != null) {
                                HBox hBox = new HBox();
                                Text name;
                                if (!user.equals(fromUser)) {
                                    if (msg.getUserList().contains(user)) {
                                        name = new Text(user.getNickName() + " (" + user.getAccount() + ")    在线");
                                    } else {
                                        name = new Text(user.getNickName() + " (" + user.getAccount() + ")    离线");
                                    }
                                    name.setFont(new Font(18));
                                    hBox.getChildren().addAll(name);
                                    setGraphic(hBox);
                                } else {
                                    users.remove(user);
                                }
                            }
                        }
                    };
                }
            });
            logger.info("setUserList() method Exit");
        });
    }

    @FXML
    public void sendButtonAction() {
        if (toUser == null && type != Type.GROUPCHAT) {
            chooseUser();
        } else {
            String message = messageBox.getText();
            if (message != null && !message.equals("")) {
                Listener.send(message, fromUser, toUser, type);
                messageBox.clear();
            }
        }
    }

    @FXML
    public void chatClick(MouseEvent mouseEvent) {
        if (mouseEvent.getButton() == MouseButton.PRIMARY && mouseEvent.getClickCount() == 1) {
            if (userList.getSelectionModel().selectedItemProperty().getValue() != null) {
                User toUser = (User) userList.getSelectionModel().selectedItemProperty().getValue();
                this.setToUser(toUser);
                setType(Type.CHAT);
                Listener.send("", fromUser, toUser, Type.CHAT);
            }
        }
    }

    public void intoChatRoom(MouseEvent mouseEvent) {
        if (mouseEvent.getButton() == MouseButton.PRIMARY && mouseEvent.getClickCount() == 1) {
            setType(Type.GROUPCHAT);
            Listener.send("", fromUser, null, Type.GROUPCHAT);
        }
    }

    public synchronized void addToChat(Message msg) {

        Platform.runLater(() -> {
            User fromUser = msg.getFrom();
            User toUser = msg.getTo();

            setMessage(msg);
            Map<String, List<MessageRecord>> listMap = msg.getListMap();
            List<String> list = new ArrayList<>();
            String key1 = fromUser.getAccount() + "-" + toUser.getAccount();
            String key2 = toUser.getAccount() + "-" + fromUser.getAccount();
            if (listMap.containsKey(key1) || listMap.containsKey(key2)) {
                List<MessageRecord> messageRecords;

                messageRecords = listMap.containsKey(key1) ? listMap.get(key1) : listMap.get(key2);

                for (MessageRecord messageRecord : messageRecords) {
                    list.add(messageRecord.getFromUser().getNickName() + " " + messageRecord.getTime() + " \r\n\t" + messageRecord.getContext());
                }

            }
            ObservableList observableList = FXCollections.observableList(list);
            messageList.setItems(observableList);
            messageList.setCellFactory(new MyCallBack());
        });
    }

    public void addToChatRoom(Message msg) {
        Platform.runLater(() -> {
            Map<String, List<MessageRecord>> listMap = msg.getListMap();
            List<String> list = new ArrayList<>();
            String key = "groupChat";
            if (listMap.containsKey(key)) {
                List<MessageRecord> messageRecords;

                messageRecords = listMap.get(key);

                for (MessageRecord messageRecord : messageRecords) {
                    list.add(messageRecord.getFromUser().getNickName() + " " + messageRecord.getTime() + " \r\n\t" +
                            messageRecord.getContext().replace("\r\n", "\r\n\t"));
                }

            }
            ObservableList observableList = FXCollections.observableList(list);
            messageList.setItems(observableList);
            messageList.setCellFactory(new MyCallBack());
        });
    }

    public void sendByEnter(KeyEvent keyEvent) {
        if (keyEvent.getCode() == KeyCode.ENTER && keyEvent.isShiftDown()) {
            sendButtonAction();
        }
    }

    public void chooseUser() {
        Platform.runLater(() -> {
            AlertUtil.alert("消息", "请选择好友", Alert.AlertType.CONFIRMATION, ButtonType.OK);
        });
    }



    /**
     * 导出消息记录
     */
    public void exportChat() {
        Map<String, List<MessageRecord>> listMap = message.getListMap();
        List<String> list = new ArrayList<>();
        String key1 = fromUser.getAccount() + "-" + toUser.getAccount();
        String key2 = toUser.getAccount() + "-" + fromUser.getAccount();
        if (listMap.containsKey(key1) || listMap.containsKey(key2)) {
            List<MessageRecord> messageRecords;

            messageRecords = listMap.containsKey(key1) ? listMap.get(key1) : listMap.get(key2);

            for (MessageRecord messageRecord : messageRecords) {
                list.add(messageRecord.getFromUser().getNickName() + " " + messageRecord.getTime() + " : " + messageRecord.getContext());
            }

            Stage stage = new Stage();
            FileChooser fileChooser = new FileChooser();
            fileChooser.setTitle("保存消息记录");
            File file = fileChooser.showSaveDialog(stage);
            if (file != null) {
                IOUtil.export(file, list);
            }
        }
    }

    /**
     * 发送文件
     */
    public void sendFileAction() {
        FileChooser fileChooser = new FileChooser();
        File file = fileChooser.showOpenDialog(new Stage());
        if (file != null) {
            byte[] fileContext = null;
            try {
                fileContext = IOUtil.getBytes(file);

                if (type == Type.CHAT) {
                    Listener.sendFile(fileContext, fromUser, toUser, Type.SENDFILE, file.getName());
                } else if (type == Type.GROUPCHAT) {
                    AlertUtil.alert("消息", "暂不支持该功能", Alert.AlertType.WARNING, ButtonType.OK);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    }

    /**
     * 接收文件
     * @param msg
     */
    public void acceptFile(Message msg) {
        Platform.runLater(() -> {
            Optional<ButtonType> buttonType = AlertUtil.alert("消息", "好友" + msg.getFrom().getNickName() + "给你发送了一个文件" + msg.getFileName() + "，是否接收",
                    Alert.AlertType.CONFIRMATION, ButtonType.OK, ButtonType.CANCEL);

            if (buttonType.isPresent() && buttonType.get() == ButtonType.OK) {
                FileChooser fileChooser = new FileChooser();
                File file = fileChooser.showSaveDialog(new Stage());
                if (file != null) {
                    try {
                        byte[] fileContext = msg.getFileContext();
                        IOUtil.getFile(fileContext, file);

                        AlertUtil.alert("消息", "接收成功", Alert.AlertType.CONFIRMATION, ButtonType.OK);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                } else {
                    AlertUtil.alert("消息", "未选择文件，接收失败", Alert.AlertType.WARNING, ButtonType.OK);
                }
            }
        });
    }

    /**
     * 文件发送失败
     */
    public void sendFail() {
        Platform.runLater(() -> {
            AlertUtil.alert("消息", "对方不在线，发送失败", Alert.AlertType.WARNING, ButtonType.OK);
        });
    }
}